package cn.bigfire.wedesk.net.fivesocket.codec;


import cn.bigfire.wedesk.net.fivesocket.frame.BinaryFiveFrame;
import cn.bigfire.wedesk.net.fivesocket.frame.CloseFiveFrame;
import cn.bigfire.wedesk.net.fivesocket.frame.ContinueFiveFrame;
import cn.bigfire.wedesk.net.fivesocket.frame.OpCodes;
import cn.bigfire.wedesk.net.fivesocket.frame.TextFiveFrame;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

/**
 * 应用层协议
 * FiveSocket 一个根据websocket简化得到的
 * 数据报文头只占5个字节
 */
public class FiveSocketDecoder extends ByteToMessageDecoder {

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {
        try {
//            ByteUtil.log(buffer, true);
            if (buffer.readableBytes() >= 5) {
                buffer.markReaderIndex();//读取之前先备份一下位置
                byte opCode = buffer.readByte();
                //弹性len字段(可压缩空间，但编解码繁琐)
//                int len = 0;
//                byte byteLen = buffer.readByte();
//                if (byteLen <= 125) {
//                    len = byteLen;
//                } else if (byteLen == 126) {
//                    len = buffer.readShort();
//                } else if(byteLen == 127) {
//                    len = buffer.readInt();
//                }
                //固定int4字节len字段(固定4字节,但编解码简单)
                int len = buffer.readInt();
                if (buffer.readableBytes() >= len) {   //Length 是Value的长度
                    //够读取一个完整 数据包 了
                    byte[] bytes = new byte[len];
                    buffer.readBytes(bytes);
                    //构建一个新的ByteBuf对象存应用层数据
                    ByteBuf outBuf = Unpooled.copiedBuffer(bytes);
                    if (OpCodes.CONTINUE_CODE == opCode) {
                        out.add(new ContinueFiveFrame(true, 0, outBuf));
                    } else if (OpCodes.TEXT_CODE == opCode) {
                        out.add(new TextFiveFrame(true, 0, outBuf));
                    } else if (OpCodes.BINARY_CODE == opCode) {
                        out.add(new BinaryFiveFrame(true, 0, outBuf));
                    } else if (OpCodes.CLOSE_CODE == opCode) {
                        out.add(new CloseFiveFrame(true, 0, outBuf));
                    } else if (OpCodes.PING_CODE == opCode) {
                        out.add(new ContinueFiveFrame(true, 0, outBuf));
                    } else if (OpCodes.PONG_CODE == opCode) {
                        out.add(new ContinueFiveFrame(true, 0, outBuf));
                    }else {
                        System.err.println("错误的OpCode:" + opCode);
                    }
                } else {
                    buffer.resetReaderIndex();//复位一下前面已经读取掉的几个字节
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
